package ink.ykb.droolstest.service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.kie.api.KieBase;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import ink.ykb.droolstest.config.ResponseMsg;
import ink.ykb.droolstest.config.ServiceException;
import ink.ykb.droolstest.dao.QishuDao;
import ink.ykb.droolstest.dao.QudaoDao;
import ink.ykb.droolstest.dao.QudaoluyouDao;
import ink.ykb.droolstest.dao.ShanghuDao;
import ink.ykb.droolstest.dao.YinhangDao;
import ink.ykb.droolstest.drools.dto.QudaoRetaReq;
import ink.ykb.droolstest.drools.dto.RetaDto;
import ink.ykb.droolstest.entity.Qishu;
import ink.ykb.droolstest.entity.Qudao;
import ink.ykb.droolstest.entity.Qudaoluyou;
import ink.ykb.droolstest.entity.Shanghu;
import ink.ykb.droolstest.entity.Yinhang;
import ink.ykb.droolstest.service.dto.QudaoluyouDto;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class QdpzService {
	
	@Autowired
	private QudaoluyouDao qudaoluyouDao;
	@Autowired
	private QudaoDao qudaoDao;
	@Autowired
	private QishuDao qishuDao;
	@Autowired
	private YinhangDao yinhangDao;
	@Autowired
	private ShanghuDao shanghuDao;
	@Autowired
	private KieBase kieBase;

	@CacheEvict(cacheNames = "qudaoluyouDtoList",key="'qudaoluyouDtoList'")
	@Transactional
	public void addQudaoluyou(Qudaoluyou qudaoluyou) {
		
		List<Qudaoluyou> dbQudaoluyouList = qudaoluyouDao.createLambdaQuery()
    			.andEq(Qudaoluyou::getShanghuid, qudaoluyou.getShanghuid())
    			.andEq(Qudaoluyou::getQudaoid, qudaoluyou.getQudaoid())
    			.andEq(Qudaoluyou::getQishuid, qudaoluyou.getQishuid())
    			.andEq(Qudaoluyou::getYinhangid, qudaoluyou.getYinhangid())
    			.andEq(Qudaoluyou::getStatus, 1)
    			.select();
	    if(qudaoluyou.getId() == null){
	    	
	    	if(dbQudaoluyouList != null && dbQudaoluyouList.size() > 0 ){
	    		throw new ServiceException(ResponseMsg.CODE_FAIL, "此配置已经存在");
	    	}
	    	qudaoluyou.setStatus(1);
	    	qudaoluyou.setCreateTime(new Date());
	        qudaoluyouDao.insert(qudaoluyou);
	    }else{
	    	
	    	if(dbQudaoluyouList != null && dbQudaoluyouList.size() > 0 && !dbQudaoluyouList.get(0).getId().equals(qudaoluyou.getId())){
	    		throw new ServiceException(ResponseMsg.CODE_FAIL, "此配置已经存在");
	    	}
	        qudaoluyouDao.updateTemplateById(qudaoluyou);
	    }
	}
	
	@CacheEvict(cacheNames = "qudaoluyouDtoList",key="'qudaoluyouDtoList'")
	@Transactional
	public void deleteQudaoluyou(Integer id) {
		Qudaoluyou dbQudaoluyou = qudaoluyouDao.single(id);
		if(dbQudaoluyou != null) {
			dbQudaoluyou.setStatus(0);
			qudaoluyouDao.updateById(dbQudaoluyou);
		}
	}

	@Cacheable(cacheNames = "qudaoluyouDtoList",key="'qudaoluyouDtoList'")
	public List<QudaoluyouDto> getQudaoluyouList() {
		
		List<Qudaoluyou>  dbQudaoluyouList =  qudaoluyouDao.createLambdaQuery()
    			.andEq(Qudaoluyou::getStatus, 1)
    			.select();
	    
		List<QudaoluyouDto> list = new ArrayList<>();
		
		dbQudaoluyouList.forEach(db -> {
			QudaoluyouDto q = new QudaoluyouDto();
			BeanCopier.create(Qudaoluyou.class, QudaoluyouDto.class, false).copy(db, q, null);
			Qishu qishu = this.qishuDao.single(q.getQishuid());
			q.setQishuName(qishu.getName());
			q.setQishu(qishu.getQishu());
			q.setQudaoName(this.qudaoDao.single(q.getQudaoid()).getName());
			q.setShanghuName(this.shanghuDao.single(q.getShanghuid()).getName());
			Yinhang dbYinhang = this.yinhangDao.single(q.getYinhangid());
			q.setYinhangName(dbYinhang.getName());
			q.setYinhangCode(dbYinhang.getCode());
			
			BigDecimal feilvamaxmount = q.getMaxamount().divide(
					new BigDecimal(1).add(q.getFeilv().divide(new BigDecimal(100))),2,RoundingMode.HALF_DOWN);
			
			q.setFeilvamaxmount(feilvamaxmount);
			
			list.add(q);
		});
		
		sortQudaoluyouDto(list);
		
	     return list;
	}
	
	public QudaoluyouDto getQudaoluyouDto(Integer id) {
			Qudaoluyou dbQudaoluyou = qudaoluyouDao.single(id);
		
			QudaoluyouDto dto = new QudaoluyouDto();
			BeanCopier.create(Qudaoluyou.class, QudaoluyouDto.class, false).copy(dbQudaoluyou, dto, null);
			Qishu qishu = this.qishuDao.single(dto.getQishuid());
			dto.setQishuName(qishu.getName());
			dto.setQishu(qishu.getQishu());
			dto.setQudaoName(this.qudaoDao.single(dto.getQudaoid()).getName());
			dto.setShanghuName(this.shanghuDao.single(dto.getShanghuid()).getName());
			Yinhang dbYinhang = this.yinhangDao.single(dto.getYinhangid());
			dto.setYinhangName(dbYinhang.getName());
			dto.setYinhangCode(dbYinhang.getCode());
			
			return dto;
	}
	
	public List<Qudao> getQudaoList() {
		return qudaoDao.all();
	}
	
	public List<Yinhang> getYinhangList() {
		return yinhangDao.all();
	}
	
	public List<Qishu> getQishuList() {
		return qishuDao.createLambdaQuery().orderBy(Qishu::getQishu).select();
	}
	
	public List<Shanghu> getShanghuList() {
	    return shanghuDao.all();
	}

	public RetaDto getRate(QudaoRetaReq qudaoRetaReq) {
		
		if(qudaoRetaReq == null || qudaoRetaReq.getShanghuid() == null) {
			throw new ServiceException(ResponseMsg.CODE_FAIL, "商户ID必传");
		}
		
		List<QudaoluyouDto> qudaoluyouList = this.getQudaoluyouList();
		if(qudaoluyouList.size() == 0) {
			return new RetaDto();
		}
		
		KieSession kieSession = kieBase.newKieSession();
		qudaoluyouList.forEach( dto -> {
			kieSession.insert(dto);
		});
		
		RetaDto retaDto =new RetaDto();
		kieSession.setGlobal("qudaoRetaReq", qudaoRetaReq);
		kieSession.setGlobal("retaDto", retaDto);
		kieSession.fireAllRules();
		
		kieSession.dispose();
		
		sortQudaoluyouDto(retaDto.getList());
		return retaDto;
	}

	/**
	 * 字段依次从小到大排序
	 * @param list
	 */
	private void sortQudaoluyouDto(List<QudaoluyouDto> list) {
		Collections.sort(list, new Comparator<QudaoluyouDto>() {

			@Override
			public int compare(QudaoluyouDto o1, QudaoluyouDto o2) {
				if(o1.getStatus() != null && o2.getStatus() != null ) {
					int sort = o1.getStatus().compareTo(o2.getStatus());
					if(sort > 0 ) {
						return 1;
					}else if(sort < 0 ) {
						return -1;
					}else {
						if(o1.getShanghuName() != null && o2.getShanghuName() != null ) {
							sort = o1.getShanghuName().compareTo(o2.getShanghuName());
							if(sort > 0 ) {
								return 1;
							}else if(sort < 0 ) {
								return -1;
							}else {
								if(o1.getQudaoName() != null && o2.getQudaoName() != null ) {
									sort = o1.getQudaoName().compareTo(o2.getQudaoName());
									if(sort > 0 ) {
										return 1;
									}else if(sort < 0 ) {
										return -1;
									}else {
										if(o1.getYinhangName() != null && o2.getYinhangName() != null ) {
											sort = o1.getYinhangName().compareTo(o2.getYinhangName());
											if(sort > 0 ) {
												return 1;
											}else if(sort < 0 ) {
												return -1;
											}else {
												if(o1.getQishu() != null && o2.getQishu() != null ) {
													sort = o1.getQishu().compareTo(o2.getQishu());
													if(sort > 0 ) {
														return 1;
													}else if(sort < 0 ) {
														return -1;
													}else {
														if(o1.getFeilv() != null && o2.getFeilv() != null ) {
															sort = o1.getFeilv().compareTo(o2.getFeilv());
															if(sort > 0 ) {
																return 1;
															}else if(sort < 0 ) {
																return -1;
															}else {
																if(o1.getMinamount() != null && o2.getMinamount() != null ) {
																	sort = o1.getMinamount().compareTo(o2.getMinamount());
																	if(sort > 0 ) {
																		return 1;
																	}else if(sort < 0 ) {
																		return -1;
																	}else {
																		if(o1.getMaxamount() != null && o2.getMaxamount() != null ) {
																			sort = o1.getMaxamount().compareTo(o2.getMaxamount());
																			if(sort > 0 ) {
																				return 1;
																			}else if(sort < 0 ) {
																				return -1;
																			}else {
																				return 0;
																			}
																		}
																	}
																}
															}
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
				return 0;
			}
		} );
	}
}
